<!--
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->

<!--
The `core-tooltip` element creates a hover tooltip centered for the content
it contains. It can be positioned on the top|bottom|left|right of content using
the `position` attribute.

To include HTML in the tooltip, include the `tip` attribute on the relevant
content.

<b>Example</b>:

    <core-tooltip label="I'm a tooltip">
      <span>Hover over me.</span>
    </core-tooltip>

<b>Example</b> - positioning the tooltip to the right:

    <core-tooltip label="I'm a tooltip to the right" position="right">
      <core-icon-button icon="drawer"></core-icon-button>
    </core-tooltip>

<b>Example</b> - no arrow and showing by default:

    <core-tooltip label="Tooltip with no arrow and always on" noarrow show>
      <img src="image.jpg">
    </core-tooltip>

<b>Example</b> - disable the tooltip.

    <core-tooltip label="Disabled label never shows" disabled>
      ...
    </core-tooltip>

<b>Example</b> - rich tooltip using the `tip` attribute:

    <core-tooltip>
      <div>Example of a rich information tooltip</div>
      <div tip>
        <img src="profile.jpg">Foo <b>Bar</b> - <a href="#">@baz</a>
      </div>
    </core-tooltip>

By default, the `tip` attribute specifies the HTML content for a rich tooltip.
You can customize this attribute with the `tipAttribute` attribute:

    <core-tooltip tipAttribute="htmltooltip">
      <div>Example of a rich information tooltip</div>
      <div htmltooltip>
        ...
      </div>
    </core-tooltip>

@group Polymer Core Elements
@element core-tooltip
@extends paper-focusable
@homepage http://www.polymer-project.org/components/core-tooltip/index.html
-->

<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../paper-focusable/paper-focusable.html">

<!-- TODO: would be nice to inherit from label to get .htmlFor, and .control,
           but the latter is readonly. -->
<!-- TODO: support off center arrows. -->
<!-- TODO: detect mobile and apply the .large class, instead of manual
           control. -->
<!-- TODO: possibly reuse core-overlay. -->
<polymer-element name="core-tooltip" extends="paper-focusable" attributes="noarrow position label show tipAttribute" role="tooltip">
<template>

  <link rel="stylesheet" href="core-tooltip.css">
  <div id="tooltip" hidden?="{{!hasTooltipContent}}"
       class="core-tooltip {{position}} {{ {noarrow: noarrow, show: show && !disabled} | tokenList}}">
    <content id="c" select="[{{tipAttribute}}]">{{label}}</content>
  </div>

  <content></content>

</template>
<script>

  Polymer({

    /**
     * A simple string label for the tooltip to display. To display a rich
     * HTML tooltip instead, omit `label` and include the `tip` attribute
     * on a child node of `core-tooltip`.
     *
     * @attribute label
     * @type string
     * @default null
     */
    label: null,

    computed: {
      // Indicates whether the tooltip has a set label propety or
      // an element with the `tip` attribute.
      hasTooltipContent: 'label || !!tipElement'
    },

    publish: {
      /**
       * Forces the tooltip to display. If `disabled` is set, this property is ignored.
       *
       * @attribute show
       * @type boolean
       * @default false
       */
      show: {value: false, reflect: true},

      /**
       * Positions the tooltip to the top, right, bottom, left of its content.
       *
       * @attribute position
       * @type string
       * @default 'bottom'
       */
      position: {value: 'bottom', reflect: true},

      /**
       * If true, the tooltip an arrow pointing towards the content.
       *
       * @attribute noarrow
       * @type boolean
       * @default false
       */
      noarrow: {value: false, reflect: true}
    },

    /**
     * Customizes the attribute used to specify which content
     * is the rich HTML tooltip.
     *
     * @attribute tipAttribute
     * @type string
     * @default 'tip'
     */
    tipAttribute: 'tip',

    attached: function() {
      this.updatedChildren();
    },

    updatedChildren: function () {
      this.tipElement = null;

      for (var i = 0, el; el = this.$.c.getDistributedNodes()[i]; ++i) {
        if (el.hasAttribute && el.hasAttribute('tip')) {
          this.tipElement = el;
          break;
        }
      }

      // Job ensures we're not double calling setPosition() on DOM attach.
      this.job('positionJob', this.setPosition);

      // Monitor children to re-position tooltip when light dom changes.
      this.onMutation(this, this.updatedChildren);
    },

    labelChanged: function(oldVal, newVal) {
      this.job('positionJob', this.setPosition);
    },

    positionChanged: function(oldVal, newVal) {
      this.job('positionJob', this.setPosition);
    },

    setPosition: function() {
      var controlWidth = this.clientWidth;
      var controlHeight = this.clientHeight;
      var toolTipWidth = this.$.tooltip.clientWidth;
      var toolTipHeight = this.$.tooltip.clientHeight;

      switch (this.position) {
        case 'top':
        case 'bottom':
          this.$.tooltip.style.left = (controlWidth - toolTipWidth) / 2 + 'px';
          this.$.tooltip.style.top = null;
          break;
        case 'left':
        case 'right':
          this.$.tooltip.style.left = null;
          this.$.tooltip.style.top = (controlHeight - toolTipHeight) / 2 + 'px';
          break;
      }
    }
  });

</script>
</polymer-element>
